home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / MATV.ZIP / MATV.DOC < prev    next >
Encoding:
Text File  |  1993-10-11  |  27.9 KB  |  707 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.           Matv v1.0
  20.           An Simple Matrix Class
  21.  
  22.           Mark Von Tress, Ph.D.
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.           PO Box 171173
  47.           Arlington TX 76003
  48.  
  49.  
  50.           Compuserve User ID : 71530,1170
  51.  
  52.  
  53.           Date: October 10, 1993
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.           You are responsible for what you do with the
  64.           code. Here is a formal disclaimer:
  65.  
  66.  
  67.           DISCLAIMER: THIS PROGRAM IS PROVIDED AS IS, WITHOUT ANY
  68.           WARRANTY, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  69.           TO FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR DISCLAIMS
  70.           ALL LIABILITY FOR DIRECT OR CONSEQUENTIAL DAMAGES RESULTING
  71.           FROM USE OF THIS PROGRAM.
  72.  
  73.  
  74.           Copyright (c) Mark Von Tress 1993
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.           ----------- Matv v1.0 - A Simple Matrix Class: Page 3 --------- 
  83.  
  84.  
  85.                                   Table of Contents
  86.  
  87.  
  88.           I. INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . .   4
  89.  
  90.           II. FINANCIAL CONDITIONS OF USE . . . . . . . . . . . . . . .   5
  91.  
  92.           III. BASIC ALGORITHMS . . . . . . . . . . . . . . . . . . . .   5
  93.                A. The Vector Class  . . . . . . . . . . . . . . . . . .   5
  94.                B. Vector Copy Constructor and Destructor  . . . . . . .   7
  95.                C. Assignment  . . . . . . . . . . . . . . . . . . . . .   8
  96.                E. Garbage(), PurgeVectors(), and SetupVectors() . . . .  10
  97.                F. Matrix Class  . . . . . . . . . . . . . . . . . . . .  10
  98.  
  99.           IV. FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . .  12
  100.                A. Unary Matrix Functions  . . . . . . . . . . . . . . .  12
  101.                B. Patterned Matrices  . . . . . . . . . . . . . . . . .  13
  102.                C. IO Functions  . . . . . . . . . . . . . . . . . . . .  13
  103.  
  104.           V. COMPILATION AND LIMITATIONS  . . . . . . . . . . . . . . .  13
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.           ----------- Matv v1.0 - A Simple Matrix Class: Page 4 --------- 
  113.  
  114.  
  115.           I. INTRODUCTION
  116.  
  117.           Matv  is a  simple matrix  class. The  program is  a sketch  of a
  118.           redesign of  my matrix program  YAMP. Matv is  useful in its  own
  119.           right though. I tend to like  little add-in classes that easy  to
  120.           memorize. That way I can focus on the problem at hand rather than
  121.           dig through documents for complicated details. I also think  that
  122.           this is a good property  for a class to have given the  number of
  123.           downloads of some other simple classes like the BUMP matrix class
  124.           by Clopper Almon,  and STRPP,  a string class  by Carl  Moreland.
  125.           These are two popular small classes.
  126.  
  127.           YAMP tends  to be on the  complicated side of things,  but in its
  128.           defense, it is a more ambitious program. I also wanted to correct
  129.           some of the design flaws I see in YAMP, and bring it more in line
  130.           with  current C++  styles. YAMP  was my  first C++ program,  so I
  131.           learned  enough  along the  way to  improve  it. (YAMP  v2.0 will
  132.           probably be released in Winter of 94.)
  133.  
  134.           Hopefully Matv is more  intuitive and portable. I have  tested it
  135.           in  Borland C++ (DOS,  Phar-Lap Dos Extender  Lite, and Easywin),
  136.           Visual  C++  (DOS and  QuickWin),  Symantec C++  (DOS,  DOSX, and
  137.           Winc), and djgpp (DOS 32-bit  protected mode). Matv is restricted
  138.           to 64K matrices for  the sake of DOS, but it is easily adapted to
  139.           larger matrices in programs compiled with DOS extenders.
  140.  
  141.           Matv uses a method for  passing matrices that I have not  seen in
  142.           most matrix classes. Most classes use  reference counting to keep
  143.           track  of number of objects  accessing a the  matrix storage. The
  144.           storage is deleted once the reference count goes to zero. This is
  145.           a standard technique in  strings. Reference counting for matrices
  146.           is overkill  since matrix storage  need never be  referenced more
  147.           than  twice during  parameter  passing.  Reference counting  also
  148.           allows  side effects  due  to  multiple  accesses to  the  matrix
  149.           storage.
  150.  
  151.           Instead, Matv uses  a "deletion  responsibility" technique.  Many
  152.           matrices  may point to the matrix storage (aliases), but only one
  153.           may delete  the storage. When a  temporary matrix is about  to be
  154.           deleted by a function  return, and the temporary is  the returned
  155.           object, then  Matv lets you transfer  the deletion responsibility
  156.           of the matrix storage to the recieving copy. The copy constructor
  157.           then  may merely  capture the storage  base pointer,  rather than
  158.           allocate new storage and copy the  data. I think of a trapeze act
  159.           when  I  read the  copy constructor.  The  trapeze is  the matrix
  160.           object  and the Flying Walinda is the matrix storage. Think about
  161.           it.
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.           ----------- Matv v1.0 - A Simple Matrix Class: Page 5 --------- 
  170.  
  171.  
  172.           II. FINANCIAL CONDITIONS OF USE
  173.  
  174.           If you  like this program, send  me $5.00 US (or  buy a deserving
  175.           beggar  lunch. In either case,  find a way  to repay my charity.)
  176.           You  may  distribute  the  package  unchanged.  I  only  plan  to
  177.           distribute it electronically. I retain the copyright  as proof of
  178.           authorship.
  179.  
  180.  
  181.           III. BASIC ALGORITHMS
  182.  
  183.                A. The Vector Class
  184.  
  185.           Matv  has two important classes: Vector and Matrix. The Vector is
  186.           the  public parent class of the Matrix class. The Vector class is
  187.           responsible for memory allocation, and no math. The Matrix  class
  188.           is  responsible  for  math, and  is  not  responsible  for memory
  189.           allocation.  The Vector class is  set up to  provide a consistant
  190.           interface to memory  managers. This way,  you modify Vector,  and
  191.           not  Matrix,  when  you  want  to  change  to   different  memory
  192.           management  strategies,  such  as  virtual matrices,  or  32  bit
  193.           vectors. The Vector class is given by 
  194.  
  195.           typedef enum bboolean { FFALSE, TTRUE } bboolean;
  196.  
  197.           class Vector
  198.           {
  199.           private :
  200.              FLOAT *c;           // vector of FLOATs
  201.              int n;              // number of FLOATs
  202.              bboolean CanDelete; // Gives permission to delete c -         
  203.                                  // initially true
  204.              bboolean CanAlias;  // Can be aliased - initially true
  205.              long signature;     // for heap checking
  206.              FLOAT *SetupVectors(int n);
  207.              void PurgeVectors(void);
  208.              
  209.           public :
  210.              Vector(void);
  211.              Vector(int n);
  212.              Vector(int n, FLOAT *x);
  213.              Vector(Vector &a);
  214.              Vector &operator = (Vector &a);
  215.              ~ Vector();
  216.              
  217.              FLOAT &operator() (int i);
  218.              int rows(void) { return n; }
  219.  
  220.              static FLOAT Nrerror(const char *errormsg);
  221.              void Garbage(const char *errormsg);
  222.              
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.           ----------- Matv v1.0 - A Simple Matrix Class: Page 6 --------- 
  231.  
  232.              friend ostream &operator << (ostream &s, Vector &v);
  233.              void release() { if (CanAlias == TTRUE) CanDelete = FFALSE; }
  234.              void CannotAlias() { CanAlias = FFALSE; }
  235.              
  236.           };
  237.  
  238.           The class  uses  an enumerated  type bboolean,  which has  values
  239.           0=FFALSE, and  1=TTRUE. There are so many  boolean classes hidden
  240.           in other libraries, I thought I would make one of my own to avoid
  241.           any  conflicts. Just use the  first letter twice  in the bboolean
  242.           type. 
  243.  
  244.           Also  note "FLOAT" instead of "float". You may configure Matv for
  245.           using double precision instead of floating points by defining the
  246.           compiler directive USE_DOUBLES.
  247.  
  248.           The public  part of  Vector  contains the  elements of  Coplien's
  249.           standard   canonical  form:   a  default   constructor,   a  copy
  250.           constructor,  a destructor,  and an  assignment operator.  I also
  251.           like to  overload the insertion operator.  Two extra constructors
  252.           are provided. You can allocate a vector with n elements, and  you
  253.           can read  an array of n FLOATs into a Vector. The function rows()
  254.           returns  the number  of elements  of the  Vector, n,  which  is a
  255.           private variable of the Vector. Elements are accessed through the
  256.           function  call operator().  The member  functions,  release() and
  257.           CannotAlias() control  the  flow through  the  copy  constructor,
  258.           destructor, and assignment operator.  The member Garbage() checks
  259.           the integrity of the  vector. If certian conditions are  met, the
  260.           vector  has  been  corrupted,  and  the  static  member  function
  261.           Nrerror() is called to shut down the program. 
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.           ----------- Matv v1.0 - A Simple Matrix Class: Page 7 --------- 
  270.  
  271.           The  private section of Vector  contains the base  pointer to the
  272.           storage,   c,   the  number   of   elements,   n,  the   deletion
  273.           responsibility, CanDelete, and whether or not the Vector can have
  274.           an  alias, CanAlias. The last two variables also control the flow
  275.           mentioned above. 
  276.  
  277.            
  278.                B. Vector Copy Constructor and Destructor
  279.  
  280.           You have to study the copy constructor, destructor and assignment
  281.           operator to  understand how the variables  CanDelete and CanAlias
  282.           work.  The function, release(),  sets the deletion responsibility
  283.           to FFALSE  if the vector can have an alias. Note the first branch
  284.           of the copy constructor. 
  285.  
  286.           Vector::Vector(Vector &a) : n(a.n), CanDelete(TTRUE),            
  287.                         CanAlias(TTRUE), signature(SIGNATURE)
  288.           {
  289.              if (a.CanDelete == FFALSE && a.CanAlias) {
  290.                  // a is not responsible for deleting c and a can have an  
  291.                  //alias
  292.                  c = a.c;
  293.              }
  294.              else {
  295.                  c = SetupVectors(a.n);
  296.                  FLOAT *cc = c;
  297.                  FLOAT *acc = a.c;
  298.                  int i = n;
  299.                  while (i--) *cc++ = *acc++;
  300.              }
  301.           }
  302.  
  303.  
  304.           If the vector to be copied is not responsible for deleting c, and
  305.           it can  have an alias, then  the matrix being copied  merely gets
  306.           its storage by pointing to the storage in the vector reference a.
  307.           The typical use of release is given in the code fragment
  308.  
  309.           Matrix f1( int n)
  310.           {
  311.              Matrix t=Fill(n,n,1);
  312.              t.release();
  313.              return t;
  314.           }
  315.  
  316.           Matrix x = f1(3);
  317.           x = f1(4);
  318.  
  319.           In  f1(), the deletion responsibility is released, and t can have
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.           ----------- Matv v1.0 - A Simple Matrix Class: Page 8 --------- 
  328.  
  329.           an  alias, so during the first branch  of the copy constructor is
  330.           used to  pass the copy into  x. This is faster  and requires less
  331.           storage  than  going  through  the  second  branch  of  the  copy
  332.           constructor.  Note the  copy  constructor is  also called  before
  333.           entering the assignment function, so the first branch of the copy
  334.           constructor is also used for passing t to x.
  335.  
  336.           Look at the destructor.  When t is destroyed because it  is going
  337.           out of scope, it is no longer responsible for deleting c, so c is
  338.           not purged, but n is set to zero. When a vector has an n of zero,
  339.           you are  trying to access a  deleted vector, so  the program will
  340.           stop if you call the member function Garbage().
  341.  
  342.           Vector::~Vector()
  343.           {
  344.              n = 0;
  345.              if (CanDelete == TTRUE)
  346.                 PurgeVectors();
  347.           }
  348.  
  349.                C. Assignment
  350.  
  351.           The  assignment  function must  address  the  problem of  aliased
  352.           matrices. The  problem arises  when the  incoming vector,  a, was
  353.           constructed via the first branch of copy  constructor. First, the
  354.           assignment operator  checks for  "a=a;" and returns  directly. An
  355.           alias is identified if the two vectors point to the same storage.
  356.           When a is  not responsible for deletion, then *this is given that
  357.           responsibility, and assignment returns. When a is responsible for
  358.           deleting c, then the  alias is split by creating new  storage for
  359.           *this and copying the storage. In code, we have
  360.  
  361.           Vector &Vector::operator = (Vector &a)
  362.           {
  363.              if (this == &a) return *this;
  364.              // deal with aliased storage
  365.              if (c == a.c && a.CanDelete == FFALSE) {
  366.                 // *this is aliased with a, and a is not
  367.                 // responsible for deleting c.
  368.                 CanDelete = TTRUE;
  369.                 n = a.n;
  370.                 return *this;
  371.              }
  372.              if (c == a.c && a.CanDelete == TTRUE) {
  373.                 // *this is aliased with a, and a is
  374.                 // responsible for deleting c.
  375.                  c = SetupVectors(a.n);
  376.                  CanDelete = TTRUE;
  377.              }
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.           ----------- Matv v1.0 - A Simple Matrix Class: Page 9 --------- 
  386.  
  387.              // *this is no longer aliased with a
  388.              if (n != a.n) {
  389.                  PurgeVectors();
  390.                  c = SetupVectors(a.n);
  391.              }
  392.              FLOAT *cc = c;
  393.              FLOAT *acc = a.c;
  394.              int i = n;
  395.              while (i--) *cc++ = *acc++;
  396.              return *this;
  397.           }
  398.  
  399.  
  400.           Finally,  if  a and  *this are  not  aliased, but  have different
  401.           lengths,  then the  storage  for *this  is  reallocated, and  the
  402.           storage of a.c is copied into that of *this.
  403.  
  404.  
  405.                D. Vector::CannotAlias();
  406.  
  407.           There are conditions where a matrix should not have an alias. The
  408.           member  function  CannotAlias() is  provided  to  force the  copy
  409.           constructor through the second branch. 
  410.  
  411.           The first case is  when you want a matrix to be static. You might
  412.           use  a static  matrix  to  accumulate  results of  a  calculation
  413.           between function calls:
  414.  
  415.           Matrix f2( Matrix &ref)
  416.           {
  417.              static Matrix accumulator = Fill(ref.r,ref.c,0);
  418.              accumulator.CannotAlias();
  419.              accumulator = accumulator + ref;
  420.              accumulator.release();
  421.              return accumulator;
  422.           }
  423.  
  424.           The  call of  release()  has no  effect  because of  the  call to
  425.           CannotAlias(). The accumulated storage  will be preserved  across
  426.           function calls. It would be corrupted if you called release() and
  427.           not CannotAlias().
  428.  
  429.           The second case  is when a matrix is passed in as a reference and
  430.           is  also the  return value that  had its  deletion responsibility
  431.           released:
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.           ----------- Matv v1.0 - A Simple Matrix Class: Page 10 --------- 
  440.  
  441.           Matrix f3( Matrix &ref )
  442.           {
  443.                ref.release();
  444.                return ref;
  445.           }
  446.           void f4( Matrix &z )
  447.           {
  448.                Matrix x = f3(z);
  449.           }
  450.  
  451.           Note that the storage in z is deleted when x goes out of scope if
  452.           z.CannotAlias()  has  not  been  called. (I  actually  made  this
  453.           mistake in one of the early incarnations of Matv.)
  454.  
  455.  
  456.                E. Garbage(), PurgeVectors(), and SetupVectors()
  457.  
  458.           You should check the  integrity of the matrices in  the parameter
  459.           list  of  a  function  call by  calling  Garbage.  SetupVectors()
  460.           allocates the storage for n+1 FLOATs. The value of c[0] is set to
  461.           0x5a5a,  then the  pointer  c is  incremented,  so now  c[-1]  is
  462.           0x5a5a. The value of signature is also set to 0x5a5a. A vector is
  463.           declared zero if  signature does  not equal 0x5a5a,  or if  c[-1]
  464.           does  not  equal 0x5a5a.  PurgeVectors  increments  signature and
  465.           decrements  the pointer  c.  Then c[0]  is  set to  zero.  Hence,
  466.           Garbage()  can tell  from the  heap if  aliased storage  has been
  467.           deleted. It can also tell from the vector itself. 
  468.  
  469.  
  470.                F. Matrix Class
  471.  
  472.           The Matrix class is  a public Vector.  It is responsible for  the
  473.           mathematical operations. The declaration  for the matrix is given
  474.           by:
  475.  
  476.           class Matrix : public Vector
  477.           {
  478.              public :
  479.              int r, c;
  480.  
  481.              FLOAT &operator() (int i, int j);
  482.              Matrix(void) : Vector(1), r(1), c(1) { }
  483.              Matrix(int rr, int cc) : Vector(rr*cc), r(rr), c(cc) { }
  484.              Matrix(int rr, int cc, FLOAT *x) : Vector(rr*cc,x), r(rr),    
  485.                        c(cc) { }
  486.              Matrix(Matrix &a) : Vector(a), r(a.r), c(a.c) { }
  487.              Matrix &operator = (Matrix &a);
  488.              ~ Matrix() { }
  489.              friend ostream &operator << (ostream &s, Matrix &m);
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.           ----------- Matv v1.0 - A Simple Matrix Class: Page 11 --------- 
  498.  
  499.              void show(char *str);
  500.  
  501.              // list of arithmetic friend functions and compound 
  502.              // assignment operators.
  503.              friend Matrix operator + (Matrix &a, Matrix &b);
  504.              friend Matrix operator + (Matrix &a, FLOAT b);
  505.              friend Matrix operator + (FLOAT b, Matrix &a);
  506.              Matrix &operator += ( Matrix &a );
  507.              Matrix &operator += ( FLOAT b );
  508.  
  509.              friend Matrix operator - (Matrix &a, Matrix &b);
  510.              friend Matrix operator - (Matrix &a, FLOAT b);
  511.              friend Matrix operator - (FLOAT b, Matrix &a);
  512.              Matrix &operator -= ( Matrix &a );
  513.              Matrix &operator -= ( FLOAT b );
  514.              friend Matrix operator - (Matrix &a); // unary minus
  515.  
  516.              friend Matrix operator * (Matrix &a, Matrix &b);
  517.              friend Matrix operator * (Matrix &a, FLOAT b);
  518.              friend Matrix operator * (FLOAT b, Matrix &a);
  519.              Matrix &operator *= ( Matrix &a );
  520.              Matrix &operator *= ( FLOAT b );
  521.  
  522.              friend Matrix operator % (Matrix &a, Matrix &b); // emult
  523.              friend Matrix operator % (FLOAT b, Matrix &a);
  524.              friend Matrix operator % (Matrix &a, FLOAT b);
  525.              Matrix &operator %= ( Matrix &a );
  526.              Matrix &operator %= ( FLOAT b );
  527.  
  528.              friend Matrix operator / (Matrix &a, Matrix &b);
  529.              friend Matrix operator / (Matrix &a, FLOAT b);
  530.              friend Matrix operator / (FLOAT b, Matrix &a);
  531.              Matrix &operator /= ( Matrix &a );
  532.              Matrix &operator /= ( FLOAT b );
  533.           };
  534.  
  535.           Matrices are dimensioned from 1 to r rows, and 1 to c columns. (I
  536.           know  this is usually considered bad style  to have r and c to be
  537.           public, but I don't like  to access r by  rows() or c by  cols().
  538.           It's 5 symbols to  many for my taste, and I don't  plan to change
  539.           the indexing base from 1). 
  540.  
  541.           Elements  are indexed by the function call operator () instead of
  542.           a double brackets  implemented with  a helper class.  This is  so
  543.           that  arrays of Matrix objects may be created. The array elements
  544.           are accessed using brackets.
  545.  
  546.           Note  that all  of  the constructors  are  just versions  of  the
  547.           corresponding Vector  constructors. All of  the memory allocation
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.           ----------- Matv v1.0 - A Simple Matrix Class: Page 12 --------- 
  556.  
  557.           happens  in  the  constructor  chain  where  the  base  class  is
  558.           initiallized  first.  The destructor  also  uses  the base  class
  559.           destructor to handle the memory dealocation.
  560.  
  561.           The assignment operator just sets the values of r and c, and then
  562.           calls the Vector assignment operator.
  563.  
  564.           Two  display functions  are  offered. The  insertion operator  is
  565.           overloaded, and there is a show function. You can say 
  566.  
  567.                cout << "display string\n" << x;
  568.  
  569.           or
  570.  
  571.                x.show("display string")
  572.  
  573.           to display a matrix. 
  574.  
  575.           The  standard  arithmetic  operators  are  overloaded,  and  they
  576.           commute with scalers. Also  there is a elementwise multiplication
  577.           operator  denoted by "%", which has  the same operator precidence
  578.           as  "*" and  "/".  You  may  also  use  the  arithmetic  compound
  579.           assignment  operators: +=,  -=, *=,  %=, and  /=. The  right hand
  580.           sides may be matrices or scalers.
  581.  
  582.  
  583.           IV. FUNCTIONS
  584.  
  585.                A. Unary Matrix Functions
  586.  
  587.           The unary matrix functions, are Tran(), Inv(), and Sweep(). These
  588.           calculate the transpose of a matrix, and the inverse. The program
  589.           stops if the matrix to be  inverted is not square. The inverse is
  590.           calculated using the g2sweep method. This is  a modified Gaussian
  591.           elimination. However, if the diagonal pivot is less than  1.0E-8,
  592.           then  that row and  column are  set to  zero. The  prototypes are
  593.           given below.
  594.  
  595.           Matrix Tran(Matrix &a);   // transpose
  596.           Matrix Inv(Matrix &a);    // invert - G2 sweep
  597.           Matrix Sweep(int k1, int k2, Matrix &a); // g2 sweep
  598.  
  599.           The Sweep() function  sweeps out columns k1 to k2. If k1 == 1 and
  600.           k2 == a.r, then  Sweep() returns the g2 generalized  inverse. See
  601.           matvtest.cpp  for  the  use  of  Sweep()  calculating  regression
  602.           coefficients.
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.           ----------- Matv v1.0 - A Simple Matrix Class: Page 13 --------- 
  611.  
  612.                B. Patterned Matrices
  613.  
  614.           The  patterned  matrix functions  are Fill(),  Ident(), Submat(),
  615.           Cv(), and  Ch(). Fill() creates an r x cc matrix of constants, d.
  616.           Ident()  produces  an  n  dimensional  identity matrix.  Submat()
  617.           extracts a submatrix from a. The top left corner position in a is
  618.           (lr,lc), and the bottom right corner position in a is (r,c). Cv()
  619.           vertically  concatenates two  matrices  with the  same number  of
  620.           rows.  Ch()  horizontally concatentates  two  matrices with  same
  621.           number of  columns. The prototypes  of these functions  are given
  622.           below:
  623.  
  624.           Matrix Fill(int r, int cc, FLOAT d = 0);
  625.           Matrix Ident(int n);
  626.           Matrix Submat(Matrix &a, int lr, int lc, int r, int c);
  627.           Matrix Cv( Matrix &a, Matrix &b );  // horizontal concatenation
  628.           Matrix Ch( Matrix &a, Matrix &b );  // vertical concatentation
  629.  
  630.  
  631.                C. IO Functions
  632.  
  633.           The ASCII  file structure is now the same as YAMP. It has a title
  634.           string on the  first line  that is no  longer than 80  characters
  635.           including a  carriage return '\n'.  The second line  contains two
  636.           integers. The  first is the number of rows of the matrix, and the
  637.           second is  the number of columns. The  remaining rows are rows of
  638.           data. See  catchv.dat for  an example  matrix.  Reada() reads  an
  639.           ascii matrix from filename. Writea()  writes matrix a to filename
  640.           with  the title line given by filetitle. The prototypes are given
  641.           below.
  642.  
  643.           Matrix Reada(char *filename);
  644.           void Writea(char  *filename, Matrix  &a, const char  *filetitle =
  645.           "A_Matrix");
  646.  
  647.  
  648.           V. COMPILATION AND LIMITATIONS
  649.  
  650.  
  651.           Programs using Matv must follow some simple steps:
  652.  
  653.                1.   include matv.cpp in the project definition
  654.                2.   include matv.h in each file that uses matrices. 
  655.  
  656.           Compile  and link the program. See matvtest.c for an example file
  657.           using matv. 
  658.  
  659.           Two  compiler switches may be defined.  NO_CHECKING is a speed-up
  660.           option for finished programs. It disables calls to Garbage(), and
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.           ----------- Matv v1.0 - A Simple Matrix Class: Page 14 --------- 
  669.  
  670.           range checking in the Matrix::operator()(int i, int j); function.
  671.           USE_DOUBLES  allows  you  to  use  double  precision  instead  of
  672.           floating point.
  673.  
  674.           Matv has  some  limitations.  Matrices are  limited  to  64K  for
  675.           standard  DOS  programs.  You can't  get  many  more  than 7  64K
  676.           matrices  in  a  640k  barrier  machine,  so this  limitation  is
  677.           reasonable.  The  limitation can  be changed  if you  have a  DOS
  678.           extender or a 32 bit compiler.  You should change all the ints in
  679.           the Vector class and code to unsigned longs. Then remove the size
  680.           restriction in SetupVectors(). The  technique above works well in
  681.           djgpp, under Pharlap DOS  extenders, and the the DOSX  library in
  682.           Symantec C++.  You can also resort  to huge pointers if  you want
  683.           matrices larger than 64K, but this is not very portable.
  684.  
  685.           Matv is not entirely  portable, but it is much  better than YAMP,
  686.           and  I was  pleased with  the results.  IMHO, this  will probably
  687.           continue until compiler venders have had plenty of time to comply
  688.           with the ANSI standard, which  is not yet complete. C++ is  a new
  689.           and complex language.
  690.  
  691.           It  works  well in  Borland C++  in  the small,  medium, compact,
  692.           large,  and huge DOS memory models. It  also works in EasyWin. If
  693.           you plan to  use it in EasyWin, you  should add a section  of the
  694.           code   that   calls   kbhit()   ever  200   or   so   times  that
  695.           Matrix::operator()(int  i, int  j);  is called.  This lets  other
  696.           applications get control of the system. The same statements holds
  697.           for  Visual  C++, except  you should  issue  a _wyeild()  call in
  698.           QuickWin applications instead of calls to kbhit(). 
  699.  
  700.           Symantec C++ 6.0  accepted matv  in the large  memory model,  but
  701.           bombed  on an  allocation failure  in the  small memory  model. I
  702.           can't track  it down,  so you  will have to  use the  large model
  703.           until  I figure  this out.  It also  worked in  the  large memory
  704.           model, but not the small, as a WinC application. I  was unable to
  705.           test  it as a  Win32s application because  WinC has  not yet been
  706.           ported to Win32s.  I hope Symantec  decides to do  this. It  also
  707.           failed  to compile  in the  DOSX model.  This is  because Reada()
  708.           calls  istream::>>() to read doubles, but this function is not in
  709.           the  current DOSX library. Until Symantec fixes this problem, you
  710.           need to replace Reada()  with a function that calls  fscanf() and
  711.           standard  C  file  functions  for   reading  the  data.  You  can
  712.           cannibalize Reada() from YAMP to do this. 
  713.  
  714.           The  djgpp  port  also failed  to  compile  Reada()  and Writea()
  715.           because the version I have uses  the old streams library. You can
  716.           cannibalize Reada() and  Writea() from YAMP  to get the  fscanf()
  717.           version. It works well  otherwise. Using the modifications above,
  718.           I  was  able  to  construct 500x500  matrices  without  problems.
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.           ----------- Matv v1.0 - A Simple Matrix Class: Page 15 --------- 
  727.  
  728.           Remember,  a 1000x1000 matrix of doubles takes 8 megs, so virtual
  729.           memory is really necessary for big problems. 
  730.  
  731.           The last limitation  is the scope  of the functions.  I kept  the
  732.           list  short  to  keep the  program  short.  You  can put  in  the
  733.           functions you  want. Also  try translating  some of  my functions
  734.           from YAMP, written in C++. They use similar methods.
  735.  
  736.           Anyway, Enjoy, and I hope you find this useful.
  737.